package site.yunnong.atvris.portal.service.impl;

import com.github.pagehelper.PageHelper;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import site.yunnong.atvris.common.api.Page;
import site.yunnong.atvris.common.api.ResultCodeEnum;
import site.yunnong.atvris.common.dto.CommentDeleteParam;
import site.yunnong.atvris.common.dto.NewQueryParam;
import site.yunnong.atvris.common.dto.NewSaveParam;
import site.yunnong.atvris.common.dto.NewsUpdateParam;
import site.yunnong.atvris.common.enumeration.MediaStatusEnum;
import site.yunnong.atvris.common.enumeration.MediaTypeEnum;
import site.yunnong.atvris.common.exception.YunnongBusinessException;
import site.yunnong.atvris.common.utils.IDUtils;
import site.yunnong.atvris.portal.util.SensitiveFilter;
import site.yunnong.atvris.common.utils.SqlUtils;
import site.yunnong.atvris.dao.domain.News;
import site.yunnong.atvris.dao.domain.NewsExample;
import site.yunnong.atvris.dao.domain.User;
import site.yunnong.atvris.dao.mapper.NewsMapper;
import site.yunnong.atvris.portal.service.CommentsService;
import site.yunnong.atvris.portal.service.NewsService;
import site.yunnong.atvris.service.InteractionService;
import site.yunnong.atvris.service.UserService;
import site.yunnong.atvris.service.helper.OperatorHelper;
import site.yunnong.atvris.service.vo.NewsVO;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 用户发布的动态
 *
 * @author zhangjinghao
 * @email jhzhang9102@163.com
 * @date 2021-07-09 23:45:37
 */
@Service
public class NewsServiceImpl implements NewsService {

    @Resource
    private NewsMapper newsMapper;
    @Resource
    private UserService userService;
    @Resource
    private InteractionService interactionService;
    @Resource
    private CommentsService commentsService;
    @Override
    public Page<NewsVO> queryPage(NewQueryParam param) {
        if (param.getUuid() == null) {
            throw new YunnongBusinessException(ResultCodeEnum.ERROR_PARAM_ILLEGAL, "参数异常");
        }
        NewsExample example = new NewsExample();
        example.createCriteria().andUuidEqualTo(param.getUuid())
                // 状态为审核通过或先发后审
                .andStatusIn(Arrays.asList(MediaStatusEnum.APPROVED.getValue(),MediaStatusEnum.ISSUE_REVIEW.getValue()));
        com.github.pagehelper.Page<News> page = PageHelper.startPage(param.getPageNum(), param.getPageSize()).doSelectPage(() -> {
            newsMapper.selectByExample(example);
        });
        Long uuid = OperatorHelper.isLogin() ? OperatorHelper.getLoginUuid() : null;
        List<NewsVO> list = page.getResult().stream().map(news -> buildNewsVO(uuid, news)).collect(Collectors.toList());
        return new Page<>(page.getPageNum(), page.getPageSize(), page.getTotal(), list);
        
    }
    
    private NewsVO buildNewsVO(Long uuid, News news) {
        NewsVO vo = new NewsVO();
        BeanUtils.copyProperties(news, vo);
        Integer mediaType = MediaTypeEnum.NEWS.getValue();
        vo.setLikedCount(interactionService.findMediaLikedCount(mediaType, news.getUnid()));
        if (uuid == null) {
            // 未登录
            vo.setHasSupport(false);
        } else {
            vo.setHasSupport(interactionService.findMediaLikeStatus(uuid, mediaType, news.getUnid()));
        }
        return vo;
    }

    @Override
    public NewsVO save(NewSaveParam param) {
        validateContent(param.getContent());
        News news = new News();
        BeanUtils.copyProperties(param, news);
        User user = OperatorHelper.getCurrentUser();
        news.setUnid(IDUtils.getId());
        news.setUuid(user.getUuid());
        news.setUserAvatar(user.getAvatar());
        news.setUserNickname(user.getNickname());
        news.setStatus(MediaStatusEnum.ISSUE_REVIEW.getValue());
        news.setLikedCount(0);
        news.setCommentCount(0);
        news.setShareCount(0);
        news.setCreateTime(LocalDateTime.now());
        newsMapper.insertSelective(news);
        // todo 推送相关关注人
        return buildNewsVO(user.getUuid(), news);
    }

    private void validateContent(String content) {
        if (StringUtils.isBlank(content)) {
            throw new YunnongBusinessException(ResultCodeEnum.ERROR_PARAM_ILLEGAL, "内容不可为空");
        }
        if (SensitiveFilter.containsSensitive(content)) {
            throw new YunnongBusinessException(ResultCodeEnum.ERROR_PARAM_ILLEGAL, "输入内容包含敏感词");
        }
    }

    @Override
    public int update(NewsUpdateParam param) {
        News news = new News();
        validateContent(param.getContent());
        BeanUtils.copyProperties(param, news);
        NewsExample example = new NewsExample();
        example.createCriteria().andUnidEqualTo(param.getUnid())
                .andContentEqualTo(param.getContent());
        return newsMapper.updateByExample(news, example);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int removeByUnid(Long unid) {
        NewsExample example = new NewsExample();
        example.createCriteria().andUnidEqualTo(unid);
        int count = newsMapper.deleteByExample(example);
        // 删除评论和回复
        CommentDeleteParam param = CommentDeleteParam.builder()
                .mediaId(unid)
                .mediaType(MediaTypeEnum.NEWS.getValue())
                .id(null)
                .build();
        commentsService.delComment(param);
        return count;
    }

    @Override
    public News queryByUnid(Long unid) {
        NewsExample example = new NewsExample();
        example.createCriteria().andUnidEqualTo(unid);
        List<News> newsList = newsMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(newsList)) {
            return null;
        } else {
            return newsList.get(0);
        }
    }

    @Override
    public int updateNews(News news) {
        return newsMapper.updateByPrimaryKeySelective(news);
    }

    @Override
    public Page<NewsVO> queryFollowNewsPage(NewQueryParam param) {
        Long uuid = OperatorHelper.getLoginUuid();
        Integer pageNum = param.getPageNum();
        Integer pageSize = param.getPageSize();
        // 关注ids
        Set<Long> targetIds = interactionService.findUserFollowList(uuid, pageNum, pageSize);
        // 带上本人
        targetIds.add(uuid);
        List<Long> uuidList = new ArrayList<>(targetIds);
        NewsExample example = new NewsExample();
        example.createCriteria().andUuidIn(uuidList)
                // 状态为审核通过或先发后审
                .andStatusIn(Arrays.asList(MediaStatusEnum.APPROVED.getValue(),MediaStatusEnum.ISSUE_REVIEW.getValue()));
        example.setOrderByClause(SqlUtils.generateOrderByClause("create_time", "desc"));
        com.github.pagehelper.Page<News> page = PageHelper.startPage(param.getPageNum(), param.getPageSize()).doSelectPage(() -> {
            newsMapper.selectByExample(example);
        });
        List<NewsVO> list = page.getResult().stream().map(news -> buildNewsVO(uuid, news)).collect(Collectors.toList());
        return new Page<>(page.getPageNum(), page.getPageSize(), page.getTotal(), list);
    }
}

